/**
 * 绘制发光墙体
 * @param {Earth} options.earth 渲染容器
 * @param {Array<Array>} options.positions 坐标位置 [ [lng, lat], [lng, lat]... ]
 * @param {Array} options.color 特效墙体颜色 colorArray
 * @param {Number} options.wallHeight 墙体高度
 * 
 * @returns {CustomPrimitive} CustomPrimitive实例
 */

function DrawWall(options) {
    let bottomP = []
    let topP = []
    let wallHeight = options.wallHeight || 1000
    let radian = Math.PI / 180;
    let num = options.positions.length - 1
    let length = options.positions.length

    // 顶点坐标
    /**
     * 墙体模型
     * [ 3  4  5 ]
     * [ 0  1  2 ]
     * 三角形顶点坐标示意 [ 0 1 4,  0 4 3,  1 2 5,  1 5 4 ] 
     */
    let indices = []

    // 纹理坐标 纹理上下层坐标
    let stsBottom = []
    let stsTop = []

    for (let i = 0; i < num; i++) {
        // 添加顶点坐标
        let arr = [
            i,
            i + 1,
            i + 1 + length,
            i,
            i + 1 + length,
            i + length,
        ]
        indices = indices.concat(arr)

        // 添加纹理坐标
        stsBottom.push(0.0)
        stsBottom.push(0.0)
        stsTop.push(1.0)
        stsTop.push(1.0)
    }
    // 添加最后一组纹理坐标  使纹理坐标对数与坐标数相等
    stsBottom.push(0.0)
    stsBottom.push(0.0)
    stsTop.push(1.0)
    stsTop.push(1.0)
    let sts = stsBottom.concat(stsTop)
    
    // 根据坐标  生成上下两组多边形坐标轮廓  将坐标整合用于顶点坐标编织围墙
    options.positions.forEach(point => {
        let lng = point[0] * radian
        let lat = point[1] * radian
        bottomP.push([ lng, lat, 0 ])
        topP.push([ lng, lat, wallHeight ])
    })
    const positions = bottomP.concat(topP);
    
    // 获取Geometry形状数据
    const [localPositions, center] = XE.Obj.CustomPrimitive.Geometry.getLocalPositions(positions);

    const renderState = XE.Obj.CustomPrimitive.getRenderState(true, true);
    renderState.cull.enabled = false;

    // 墙体纹理 shader语法
    const fragmentShaderSource =
        `
    varying vec3 v_positionEC;
    varying vec3 v_normalEC;
    varying vec2 v_st;
    varying vec4 v_color;
    uniform sampler2D u_image;
    uniform vec4 u_color;
    void main()
    {
        float powerRatio = fract(czm_frameNumber / 30.0) + 1.0;
        float alpha = pow(1.0 - v_st.t, powerRatio);
        gl_FragColor = vec4(u_color.rgb, alpha*u_color.a);
    }
    `;

    const config = {
        position: center,
        positions: [...localPositions],
        sts: sts,
        indices: indices,
        color: options.color || [0.5, 0.8, 1.0, 1.0],
        renderState,
        canvasWidth: 1,
        fragmentShaderSource,
    };

    const p = new XE.Obj.CustomPrimitive(options.earth);
    p.xbsjFromJSON(config);

    p._node = this
    this.XEObj = p
    this.data = options.data || null
}

DrawWall.prototype.destroy = function () {
    this.XEObj._node = null
    this.XEObj.destroy()
}

DrawWall.prototype.setShow = function (options) {
    this.XEObj.show = options
}


export default DrawWall